<script lang="ts" setup>
import { computed, reactive, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useUserStore } from "@/store/user.ts";
import { MenuUnfoldOutlined, MenuFoldOutlined } from "@ant-design/icons-vue";
import SubItem from "@/layouts/components/menu/SubItem.vue";
import { storeToRefs } from "pinia";
import { useThemeStore } from "@/store/theme.ts";
import { IRouter } from "@/utils/types/TMenu.ts";
import { MenuInfo } from "ant-design-vue/es/menu/src/interface";

const currentRoute = useRoute();
const router = useRouter();
const userStore = useUserStore();
const menus = computed(() => userStore.menuData);
const { collapsed } = storeToRefs(userStore);
const themeStore = useThemeStore();
const { menuTheme } = storeToRefs(themeStore);

// 获取当前打开的子菜单
const getOpenKeys = () => [currentRoute.matched[1]?.path];
const state = reactive({
  openKeys: getOpenKeys(),
  selectedKeys: [currentRoute.path],
});

const toMapMenuData = (
  menuData: IRouter[],
  menuDataMap: Map<string, IRouter>,
  matched: IRouter[] = [],
) => {
  menuData.forEach((v: IRouter) => {
    menuDataMap.set(v.path, { ...v, matched });
    if (v.children && v.children.length) {
      toMapMenuData(v.children, menuDataMap, [...matched, v]);
    }
  });
};

// 监听菜单收缩状态
watch(
  () => collapsed.value,
  (newVal: boolean) => {
    state.openKeys = newVal ? [] : getOpenKeys();
    state.selectedKeys = [currentRoute.path];
  },
);

const menuDataMap: Map<string, IRouter> = new Map();
// 跟随页面路由变化，切换菜单选中状态
watch(
  () => currentRoute.fullPath,
  () => {
    if (currentRoute.name === "login" || collapsed.value) {
      return;
    }
    toMapMenuData(menus.value, menuDataMap, []);
    const path = currentRoute.path;
    if (menuDataMap.has(path)) {
      const menu = menuDataMap.get(path);
      state.selectedKeys = [];
      if (menu) {
        state.selectedKeys = [menu.path];
      }
      // 设置openkeys
      if (menu?.matched) {
        const newOpenKeys = menu.matched.map(v => v.path);
        state.openKeys = [...new Set([...state.openKeys, ...newOpenKeys])];
      }
    }
  },
  { immediate: true },
);

// 点击菜单
const clickMenuItem = ({ key }: MenuInfo) => {
  if (/http(s)?:/.test(key as string)) {
    window.open(key as string);
  } else {
    router.push({ path: key as string });
  }
};
</script>

<template>
  <a-menu
    v-model:open-keys="state.openKeys"
    v-model:selected-keys="state.selectedKeys"
    :collapsed="collapsed"
    mode="inline"
    style="height: calc(100vh - 100px)"
    :theme="menuTheme"
    @click="clickMenuItem"
  >
    <template v-for="item in menus" :key="item.path">
      <SubItem :menuInfo="item" />
    </template>
  </a-menu>
  <div style="height: 50px">
    <a-menu
      class="ant-pro-sider-menu"
      mode="inline"
      :theme="menuTheme"
      @click="userStore.toggleCollapsed()"
    >
      <a-menu-item>
        <template #icon>
          <MenuUnfoldOutlined v-if="collapsed" />
          <MenuFoldOutlined v-else />
        </template>
      </a-menu-item>
    </a-menu>
  </div>
</template>
